package com.xiashitech.agent.diagnosis.util;

import com.xiashitech.agent.config.StartConfig;
import com.xiashitech.agent.instrumentation.log.XSLevel;
import com.xiashitech.interfaces.agent.dto.diagnosis.CommandReq;
import com.xiashitech.interfaces.agent.dto.diagnosis.CommandResp;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.logging.Logger;

public class DiagnosisHttpUtil {
    private static final Logger logger = Logger.getLogger(com.xiashitech.agent.utils.HttpUtil.class.getName());

    private static final String getDiagnosisCommand = "getDiagnosisCommand";

    private static String agentService;

    private static String systemId;

    private static String microServiceId;

    public static void setAgentService(String agentService) {
        DiagnosisHttpUtil.agentService = agentService;
    }

    public static String getAgentService() {
        return agentService;
    }

    public static void setSystemId(String systemId) {
        DiagnosisHttpUtil.systemId = systemId;
    }

    public static String getSystemId() {
        return systemId;
    }

    public static String getMicroServiceId() {
        return microServiceId;
    }

    public static void setMicroServiceId(String microServiceId) {
        DiagnosisHttpUtil.microServiceId = microServiceId;
    }

    public static String doGet(String url, Map<String,String> params) {
        return doGet(url,params,null,null,false);
    }

    public static String doGet(String url, Map<String,String> params, String contentType, Map<String, String> heads, boolean isHttps) {
        String response = "";
        HttpURLConnection httpURLConnection = null;
        try {
            if(isHttps) {
                url = "https://" + url;
            } else {
                url = "http://" + url;
            }
            // 拼接请求参数
            if (params != null && !params.isEmpty()) {
                url += "?";
                StringBuilder sb = new StringBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    try {
                        sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), Charset.defaultCharset().name())).append("&");
                    } catch (Throwable e) {
                        sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
                    }
                }
                sb.delete(sb.length() - 1, sb.length());
                url += sb.toString();
            }
            URL requestUrl = new URL(url);
            httpURLConnection = (HttpURLConnection) requestUrl.openConnection();
            httpURLConnection.setDoOutput(false);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.setUseCaches(true);
            httpURLConnection.setInstanceFollowRedirects(true);
            httpURLConnection.setConnectTimeout(30 * 1000);
            httpURLConnection.setReadTimeout(30 * 1000);
            if(contentType != null && !"".equals(contentType)) {
                httpURLConnection.setRequestProperty("Content-Type", contentType);
            }
            if (heads != null && !heads.isEmpty()) {
                for (Map.Entry<String, String> entry : heads.entrySet()) {
                    httpURLConnection.setRequestProperty(entry.getKey(),entry.getValue());
                }
            }
            httpURLConnection.connect();
            int code = httpURLConnection.getResponseCode();
            if (code >= 200 && code < 300) {
                InputStream is = httpURLConnection.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int context;
                while ((context = is.read()) != -1) {
                    baos.write(context);
                }
                response = baos.toString("UTF-8");
            }
        } catch (Throwable e) {
            logger.log(XSLevel.DEBUG, e.getMessage() + ", url:" + url);
        }finally {
            if (httpURLConnection != null){
                try {
                    httpURLConnection.disconnect();
                }catch (Throwable e){
                    logger.log(XSLevel.DEBUG, e.getMessage());
                }
            }
        }
        return response;
    }

    public static String doPost(String url) {
        return doPost(url,null,null,null,false);
    }

    public static String doPost(String url, String body, String contentType) {
        return doPost(url,body,contentType,null,false);
    }

    public static String doPost(String url, String body, String contentType, Map<String, String> heads, boolean isHttps) {
        String response = "";
        HttpURLConnection httpURLConnection = null;
        try {
            if(isHttps) {
                url = "https://" + url;
            } else {
                url = "http://" + url;
            }
            URL requestUrl = new URL(url);
            httpURLConnection = (HttpURLConnection)requestUrl.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setConnectTimeout(30 * 1000);
            httpURLConnection.setReadTimeout(30 * 1000);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setInstanceFollowRedirects(true);
            if(contentType != null && !"".equals(contentType)) {
                httpURLConnection.setRequestProperty("Content-Type", contentType);
            }
            if (heads != null && !heads.isEmpty()) {
                for (Map.Entry<String, String> entry : heads.entrySet()) {
                    httpURLConnection.setRequestProperty(entry.getKey(),entry.getValue());
                }
            }
            httpURLConnection.connect();
            if(body != null && !"".equals(body)) {
                OutputStream out = httpURLConnection.getOutputStream();
                out.write(body.getBytes("UTF-8"));
                out.flush();
                out.close();
            }
            int code = httpURLConnection.getResponseCode();
            if (code >= 200 && code < 300) {
                InputStream is = httpURLConnection.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int context;
                while ((context = is.read()) != -1) {
                    baos.write(context);
                }
                response = baos.toString("UTF-8");
            }
        } catch (Throwable e) {
            logger.log(XSLevel.DEBUG, e.getMessage()+ ", url:" + url);
        }finally {
            if (httpURLConnection != null){
                try {
                    httpURLConnection.disconnect();
                }catch (Throwable e){
                    logger.log(XSLevel.DEBUG, e.getMessage());
                }
            }
        }
        return response;
    }

    /**
     * 发送诊断结果
     * @param sessionId
     * @param line
     * @param diagnosisResult
     */
    public static void sendResult(Integer sessionId, String line, String diagnosisResult) {
        try {
            String result = DiagnosisJsonUtil.convertObjectToString(CommandResp.builder().systemId(DiagnosisHttpUtil.getSystemId()).microServiceId(DiagnosisHttpUtil.getMicroServiceId()).line(line).sessionId(sessionId).diagnosisResult(diagnosisResult).build());
            // doPost(DiagnosisHttpUtil.getAgentService()+ StartConfig.serverContextPath + "/v1/agent/transmitCommandResult",result,"application/json;charset=UTF-8");
            doPost(StartConfig.getAgentServiceRoot() + "/v1/agent/transmitCommandResult",result,"application/json;charset=UTF-8");
        } catch (Throwable e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * 获取该系统+该服务的诊断命令
     * @return
     */
    public static String getDiagnosisCommand() {
        try {
            CommandReq commandReq = CommandReq.builder().systemId(DiagnosisHttpUtil.getSystemId()).microServiceId(DiagnosisHttpUtil.getMicroServiceId()).build();
            String param = DiagnosisJsonUtil.convertObjectToString(commandReq);
            //String response = DiagnosisHttpUtil.doPost(DiagnosisHttpUtil.getAgentService()+StartConfig.serverContextPath + "/v1/agent/getDiagnosisCommand",param,"application/json;charset=UTF-8");
            String response = DiagnosisHttpUtil.doPost(StartConfig.getAgentServiceRoot() + "/v1/agent/getDiagnosisCommand",param,"application/json;charset=UTF-8");
            return response;
        } catch (Throwable e) {
            System.out.println(e.getMessage());
        }
        return null;
    }
}
